//
//  XTOperationViewController.m
//  XTMuteOpen
//
//  Created by bushAK on 2024/1/23.
//

#import "XTOperationViewController.h"
#import "XTCommon.h"
//#import "MTTurnServiceModel.h"
#import "AppDelegate.h"
#import <WSProgressHUD/WSProgressHUD.h>
#import "XTMuteOpen-Swift.h"
#import "XTDragMoveView.h"
 

//#import "MTActionsModel.h"
 
#define rtc_msg @"rtcmessage"

#define KYScreenHeight       ([UIScreen mainScreen].bounds.size.height)

#define KYScreenWidth        ([UIScreen mainScreen].bounds.size.width)

@interface XTOperationViewController ()<RTCVideoViewDelegate,RTCPeerConnectionDelegate, RTCDataChannelDelegate>

@property(nonatomic,strong)RTCPeerConnection *peerConnection;
@property(nonatomic,strong) RTCDataChannel *dataChannel;

@property (nonatomic, strong) SocketManager *socketManager;
@property (nonatomic, strong)  SocketIOClient * IOClient;
@property(nonatomic,strong)RTCPeerConnectionFactory *connectionFactory;

 

//@property (nonatomic, strong)   XTOperationView *operationView;
 
@property(nonatomic,strong)  RTCEAGLVideoView *EAGLVideoView;
//  视频track
@property (nonatomic, strong)   RTCVideoTrack *track;

// 是否已经连接
@property (nonatomic, assign)  BOOL isConnect;
// 是否显示悬浮球
@property (nonatomic, copy)  NSString *showFloattingBall;
// 视频流媒体的尺寸
@property (nonatomic, assign)  CGSize remoteVideoStreamSize;
@property (nonatomic, retain) XTDragMoveView *dragMoveView;
 

@property (nonatomic, assign)  RTCIceGatheringState iceGatheringState;
  
// 用于处理长时间不操作的，提醒他用户退出
@property (nonatomic, strong) NSTimer *timer;
@property (nonatomic, assign)   BOOL  actionMenuStatus;

@end

@implementation XTOperationViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    RTCInitializeSSL();
    [self createManger];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.25* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [WSProgressHUD showWithStatus:@"正在加载..."];
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [WSProgressHUD dismiss];
        });
    });
      
    [self initUI];
    [self resetTimer];
 
}

-(void)createManger{
    NSURL * url = [NSURL URLWithString:[XTCommon get_api_get_rtc_url]];
    NSString * token = [XTCommon getToken];
    NSMutableDictionary * config = [NSMutableDictionary dictionary];
    [config setValue:@YES forKey:@"polling"];
    [config setValue:@YES forKey:@"log"];
    [config setValue:@YES forKey:@"forceWebsockets"];
    [config setValue:@YES forKey:@"forcePolling"];

    [config setValue:@{@"room":self.vmModel.room,@"auth":token} forKey:@"connectParams"];
    self.socketManager = [[SocketManager alloc]initWithSocketURL:url config:config ];
    [self connectSocket];
}
// 每次操作都需要重制定时器
-(void)resetTimer{
    [self removeTimer];
    self.timer = [NSTimer scheduledTimerWithTimeInterval:5 * 60 target:self selector:@selector(handleTimer) userInfo:nil repeats:YES];
    [[NSRunLoop mainRunLoop] addTimer:self.timer forMode:NSRunLoopCommonModes];


}
-(void)removeTimer{
    if (self.timer != nil) {
        [self.timer invalidate];
        self.timer = nil;
    }
}
// 提醒用户长时间未使用
-(void)handleTimer{
    __weak __typeof(self) weakSelf = self;

    UIAlertController *alert  = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"您长时间未使用，是否替您退出并挂起云机" preferredStyle:UIAlertControllerStyleAlert];

    UIAlertAction *confirm  = [UIAlertAction actionWithTitle:@"确认" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        [weakSelf removeTimer];
       
        [weakSelf dismissViewControllerAnimated:YES completion:nil];
    }];
    [confirm setValue:[UIColor systemRedColor] forKey:@"titleTextColor"];
    [alert addAction:confirm];

    UIAlertAction *cancel  = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:cancel];
    [weakSelf presentViewController:alert animated:YES completion:nil];
}

-(void)closeAction{
    //
    if (self.IOClient) {
        [self.IOClient disconnect];
    }
    if (self.dataChannel) {
        [self.dataChannel close];
    }
    if (self.peerConnection) {
        [self.peerConnection close];
    }
}
 
-(void)createOperation{
    __weak __typeof(self) weakSelf = self;
//    self.actionMenu.itemBlock = ^(MTActionsModel * model ) {
//        if ([model.name containsString:@"主屏幕"]) {
//            NSDictionary * dict = @{@"type":@(BackToHome)};
//            [weakSelf emitChannelWithDict:dict];
//        }
//        if ([model.name containsString:@"重启"]) {
//            [weakSelf reBoot];
//        }
//        if ([model.name containsString:@"退出"]) {
//            [weakSelf goBack];
//        }
//        if ([model.name containsString:@"多任务"]) {
//            NSDictionary * dict = @{@"type":@(BackToHome)};
//            [weakSelf emitChannelWithDict:dict];
//            [weakSelf emitChannelWithDict:dict];
//        }
//        if ([model.name containsString:@"悬浮球"]) {
//            [weakSelf updateFloatBall];
//         }
//  
//        if ([model.name containsString:@"剪切板"]) {
//            [weakSelf pastToBoard];
//        }
// 
//        if ([model.name containsString:@"清理内存"]) {
//            [weakSelf clearMemAction];
//        }
//        
//        if ([model.name containsString:@"修改云机名"]) {
//            [weakSelf renamePhone:model.exit];
//        }
//        
//        
//        
//        
//        if ([model.name containsString:@"联系客服"]) {
// 
////
////            UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
////            MTServiceController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"MTServiceController"];
////
////            [weakSelf presentViewController:viewController animated:YES completion:nil];
//        }
//        
//      
//    };
    
}
-(void)renamePhone:(NSString *)name{
    
 
//    [MTNetWorkManger sendPostWithUrl:[MTConsts getUpdateNameApi]  pragam:@{@"vm_id" : self.itemModel.ID,@"new_name":name} successful:^(id responseObject) {
//        [WSProgressHUD showSuccessWithStatus:@"操作成功，可返回主页查看"];
//    } fail:^(id responseObject) {
//        [WSProgressHUD showErrorWithStatus:@"服务器繁忙，请稍后再试"];
//    } ];
    
}
-(void)reBoot{
 
    UIAlertController *alert  = [UIAlertController alertControllerWithTitle:@"你确定要重启云机吗？" message:@"会自动退出当前页面，大约需要3～5分钟才能使用" preferredStyle:UIAlertControllerStyleAlert];
    __weak __typeof(self) weakSelf = self;

    UIAlertAction *confirm  = [UIAlertAction actionWithTitle:@"重启" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
            NSDictionary * ditc = @{
                @"cmd":@"reboot",
             };
            NSData *message =
                [NSJSONSerialization dataWithJSONObject:ditc options:NSJSONWritingPrettyPrinted error:nil];
            NSString *messageStr =  [[NSString alloc] initWithData:message  encoding:NSUTF8StringEncoding];
        if (messageStr.length > 0) {
            [weakSelf.IOClient emit:rtc_msg with:@[messageStr]];
            [WSProgressHUD showSuccessWithStatus:@"操作成功，大约5分钟，即将推出当前"];
        }else{
            [WSProgressHUD showErrorWithStatus:@"数据不正确"];
        }
    

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [weakSelf dismissViewControllerAnimated:YES completion:nil];
        });
    }];
    [confirm setValue:[UIColor redColor] forKey:@"titleTextColor"];
    [alert addAction:confirm];

    UIAlertAction *cancel  = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:cancel];
    [self presentViewController:alert animated:YES completion:nil];
}
-(void)updateFloatBall{
 
    if ([self.showFloattingBall isEqualToString:@"YES"]) {
        NSDictionary * dict = @{@"type":@(ShowIosFloat)};
        [self emitChannelWithDict:dict];
        self.showFloattingBall = @"NO";

    }else{
        self.showFloattingBall = @"YES";
        NSDictionary * dic = @{@"type":@(HideIosFloat)};
        [self emitChannelWithDict:dic];
    }
}
-(void)pastToBoard{
    if ([UIPasteboard generalPasteboard].string.length == 0) {
        [WSProgressHUD showErrorWithStatus:@"请先复制内容到剪贴板"];
        return;
    }
    NSDictionary * dic = @{
        @"type":@(CopyToPhone),
        @"data":[UIPasteboard generalPasteboard].string
     };
   BOOL success = [self emitChannelWithDict:dic];
    if (success == NO) {
        [WSProgressHUD showErrorWithStatus:@"操作失败啦"];
    }else{
        [WSProgressHUD showSuccessWithStatus:@"已复制到云手机，长按输入框粘贴"];
    }
}
 
/// 清理内存
-(void)clearMemAction{
    UIAlertController *alert  = [UIAlertController alertControllerWithTitle:@"温馨提示" message:@"清理内存,您的打开的部分应用程序将会退出." preferredStyle:UIAlertControllerStyleAlert];
    __weak __typeof(self) weakSelf = self;

    UIAlertAction *confirm  = [UIAlertAction actionWithTitle:@"清理" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
 
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            [WSProgressHUD showSuccessWithStatus:@"请求成功，即将退出，请重新进入"];
            [weakSelf dismissViewControllerAnimated:YES completion:nil];

        });
    }];
    [confirm setValue:[UIColor systemRedColor] forKey:@"titleTextColor"];

    UIAlertAction *cancel  = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:nil];
    [alert addAction:confirm];
    [alert addAction:cancel];
    [self presentViewController:alert animated:YES completion:nil];
}
/** 取消*/
- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint p = [[touches anyObject]locationInView:self.EAGLVideoView];
    [self sendGesMessage:p type:DragUp];
}
/** 移动*/
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    CGPoint p = [[touches anyObject]locationInView:self.EAGLVideoView];
    [self sendGesMessage:p type:DragUpdate];
}
/** 结束*/
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event{
    CGPoint p = [[touches anyObject]locationInView:self.EAGLVideoView];
    [self sendGesMessage:p type:DragUp];
}
/** 开始*/
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    CGPoint p = [[touches anyObject]locationInView:self.EAGLVideoView];
    [self sendGesMessage:p type:DragStart];
    [self resetTimer];
}


// 发送消息通信
-(void)sendGesMessage:(CGPoint)point type:( XTMouseEventType)type{
    CGFloat height1 = 0.0;
    CGFloat width1 = 0.0;
    CGFloat vw = 0.0;
    CGFloat aspect = 0.0;
    CGFloat vedioH = 0.0;
    CGFloat tempH = 0.0;
    CGFloat halfH = 0.0;
    CGFloat tempW = 0.0;
    CGFloat halfW = 0.0;
    CGFloat InterfaceWidth = 0.0;
    CGFloat InterfaceHigh = 0.0;
    CGFloat X = 0.0;
    CGFloat Y = 0.0;

    height1 = self.EAGLVideoView.frame.size.height;
    width1 = self.EAGLVideoView.frame.size.width;
    vw = (self.remoteVideoStreamSize.width / self.remoteVideoStreamSize.height) * height1;
    aspect = width1 / vw;
    vedioH  = height1 * aspect;

    tempH = (height1 - vedioH) / 2;
    halfH = tempH > 0 ? tempH : 0;
    tempW= (width1 - vw) / 2;
    halfW = tempW > 0 ? tempW : 0;

    InterfaceWidth = vw < self.EAGLVideoView.frame.size.width ? vw : self.EAGLVideoView.frame.size.width;
    InterfaceHigh = vedioH < self.EAGLVideoView.frame.size.height ? vedioH : self.EAGLVideoView.frame.size.height;
    X = point.x - halfW;
    Y = point.y - halfH;

    NSMutableDictionary * dic = [NSMutableDictionary dictionary];
    [dic setValue:@(type) forKey:@"ActiveType"];
    [dic setValue:@(InterfaceWidth) forKey:@"InterfaceWidth"];
    [dic setValue:@(InterfaceHigh) forKey:@"InterfaceHigh"];
    [dic setValue:@(X) forKey:@"x"];
    [dic setValue:@(Y) forKey:@"y"];

    
    NSDictionary * dict = @{@"type":@(MouseEvent),
                           @"data":dic};
    [self emitChannelWithDict:dict];
}
 

//  socket连接
-(void)connectSocket{
     self.IOClient = [self.socketManager socketForNamespace:@"/signaling"];
    __weak __typeof(self) weakSelf = self;

    [self.IOClient on:@"connect" callback:^(NSArray * data, SocketAckEmitter * emitter) {
 
        if (weakSelf.isConnect == NO) {
            weakSelf.isConnect = YES;
          [weakSelf initOffer];
        }
    }];
 
    [self.IOClient on:rtc_msg callback:^(NSArray * data, SocketAckEmitter * emitter) {
        [weakSelf handleData:data];
    }];
 
    [self.IOClient connect];
}
// 处理数据
-(void)handleData:(NSArray *)d{
    if (d.count > 0) {
        NSData *jsonData = [d.firstObject dataUsingEncoding:NSUTF8StringEncoding];
       
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:jsonData
                                                                        options:NSJSONReadingMutableContainers
                                                                          error:nil];
        NSString * cmd = dic[@"cmd"];
 
        
        if ([ cmd isEqualToString:@"join"] || [ cmd isEqualToString:@"bye"] || [ cmd isEqualToString:@"unkown"] || [ cmd isEqualToString:@"offer"]) {
            NSLog(@"不需要做处理");
        }
        
        NSData *json = [dic[@"data"] dataUsingEncoding:NSUTF8StringEncoding];
       
        NSDictionary * dic2 = [NSJSONSerialization JSONObjectWithData:json  options:NSJSONReadingMutableContainers   error:nil];
        
        if ([ cmd isEqualToString:@"answer"]) {
            NSString * sdpStr = dic2[@"sdp"];//webRtcModel.data.sdp;
            if (sdpStr == nil) {
                [WSProgressHUD showErrorWithStatus:@"数据转换失败"];
                return;
            }
            RTCSessionDescription *desc  = [[RTCSessionDescription alloc]initWithType:RTCSdpTypePrAnswer sdp:sdpStr];
            [self.peerConnection setRemoteDescription:desc completionHandler:^(NSError * _Nullable error) {
            }];
        }
        if ([ cmd isEqualToString:@"candidate"]) {
            NSString * candidate = dic2[@"candidate"];
            NSNumber * label = dic2[@"label"];
            NSString * ID = dic2[@"id"];

            RTCIceCandidate *rtcIceCandidate = [[RTCIceCandidate alloc]initWithSdp:candidate sdpMLineIndex:[label intValue] sdpMid:ID];
            if (rtcIceCandidate == nil) {
                [WSProgressHUD showErrorWithStatus:@"数据转换失败"];
                return;
            }
            [self.peerConnection  addIceCandidate:rtcIceCandidate completionHandler:^(NSError * _Nullable error) {
                NSLog(@"addIceCandidate === %@",error);
             }];
        }
   
    }
    
}
- (void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    self.navigationController.navigationBar.hidden = YES;
    
}
- (void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    self.navigationController.navigationBar.hidden = YES;

}
// 初始化 peer
-(void)setUpPeer{
    [RTCPeerConnectionFactory initialize];
    
    self.connectionFactory = [XTOperationViewController getFactory];
  
    self.peerConnection = [self.connectionFactory peerConnectionWithConfiguration:[XTOperationViewController getConfigurationWithIces:self.iceTurnArray] constraints:[XTOperationViewController getConstraints] delegate:self];
 
}
// 初始化offer
-(void)initOffer{
    
    [self setUpPeer];
    
 
    RTCDataChannelConfiguration * config  =  [[RTCDataChannelConfiguration alloc]init];
    self.dataChannel = [self.peerConnection dataChannelForLabel:@"fileTransfer" configuration:config];
    self.dataChannel.delegate = self;
    __weak __typeof(self) weakSelf = self;

    [self.peerConnection offerForConstraints:[XTOperationViewController getOfferConstraint] completionHandler:^(RTCSessionDescription * _Nullable sdp, NSError * _Nullable error) {
        
        [weakSelf peerConnection:weakSelf.peerConnection  didCreateSessionDescription:sdp  error:error];
        
    }];
}
//  发送offer
- (void)peerConnection:( RTCPeerConnection  *)peerConnection
    didCreateSessionDescription:( RTCSessionDescription *)sdp
                          error:(NSError *)error {
  dispatch_async(dispatch_get_main_queue(), ^{
    if (error) {
      NSLog(@"Failed to create session description. Error: %@", error);
      return;
    }
      __weak __typeof(self) weakSelf = self;

      [self.peerConnection setLocalDescription:sdp completionHandler:^(NSError * _Nullable error) {
            
      }];
      
      NSMutableDictionary * dict = [NSMutableDictionary dictionary];
      [dict setValue:@"offer" forKey:@"cmd"];
      [dict setValue:@{
        @"sdp":sdp.sdp,
        @"type":[RTCSessionDescription stringForType:sdp.type]
    } forKey:@"data"];
      
//      NSDictionary * dict = @{
//          @"cmd":@"offer",
//          @"data":@{
//              @"sdp":sdp.sdp,
//              @"type":[RTCSessionDescription stringForType:sdp.type]
//          }
//       };
      NSData *message  =
          [NSJSONSerialization dataWithJSONObject:dict
                                          options:NSJSONWritingPrettyPrinted
                                            error:nil];
      NSString *messageStr  =
          [[NSString alloc] initWithData:message
                                encoding:NSUTF8StringEncoding];
      if (messageStr.length > 0) {
          [weakSelf.IOClient emit:rtc_msg with:@[messageStr]];

      }else{
          [WSProgressHUD showErrorWithStatus:@"数据转换失败"];
      }
       
      
  });
}


+(RTCPeerConnectionFactory *)getFactory{
    RTCDefaultVideoEncoderFactory *encoderFactory =   [[RTCDefaultVideoEncoderFactory alloc] init];

   RTCDefaultVideoDecoderFactory *decoderFactory =  [[RTCDefaultVideoDecoderFactory alloc] init];
   return  [[RTCPeerConnectionFactory alloc] initWithEncoderFactory:encoderFactory decoderFactory:decoderFactory];
}

+(RTCConfiguration *)getConfigurationWithIces:(NSArray *)ices;{
   RTCConfiguration * configuration = [[RTCConfiguration alloc]init];
    configuration.sdpSemantics = RTCSdpSemanticsUnifiedPlan;
    configuration.tcpCandidatePolicy =  RTCTcpCandidatePolicyDisabled;
    configuration.bundlePolicy = RTCBundlePolicyMaxBundle;
   configuration.rtcpMuxPolicy = RTCRtcpMuxPolicyRequire;
    configuration.iceServers =  ices;
 
   return configuration;
}
+(RTCMediaConstraints *)getConstraints {
   NSMutableDictionary * dic = [NSMutableDictionary dictionary];
    [dic setValue:@"false" forKey:@"OfferToReceiveAudio"];
   [dic setValue:@"true" forKey:@"OfferToReceiveVideo"];
   RTCMediaConstraints *con =
       [[RTCMediaConstraints alloc] initWithMandatoryConstraints:dic
                                             optionalConstraints:@{ @"DtlsSrtpKeyAgreement" : @"true" }];
   return con;
}
+(RTCMediaConstraints *)getOfferConstraint{

   NSMutableDictionary * dic = [NSMutableDictionary dictionary];
    [dic setValue:@"true" forKey:@"OfferToReceiveVideo"];

   [dic setValue:@"false" forKey:@"OfferToReceiveAudio"];

   RTCMediaConstraints* constraints = [[RTCMediaConstraints alloc] initWithMandatoryConstraints:dic optionalConstraints:nil];
   return constraints;
}

/** The data channel state changed. */
- (void)dataChannelDidChangeState: (RTCDataChannel *)dataChannel;{
    if (dataChannel.isOrdered) {
        //
        [[NSUserDefaults standardUserDefaults]setValue:@"isOrdered" forKey:@"dataChannelStatus"];
        [[NSUserDefaults standardUserDefaults] synchronize];
    }else{
        NSLog(@"还没就绪啦");
    }
 
 }

/** The data channel successfully received a data buffer. */
- (void)dataChannel:(RTCDataChannel *)dataChannel
didReceiveMessageWithBuffer:(RTCDataBuffer *)buffer;{
    if (buffer.isBinary) {
        // 发送的二进制文件
        NSLog(@"发送的二进制文件");
    }else{
        // 发送的不是二进制文件
        
    }
 }
 

/** Called when the SignalingState changed. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
didChangeSignalingState:(RTCSignalingState)stateChanged;{
    
 }

/** Called when media is received on a new stream from remote peer. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
          didAddStream:(RTCMediaStream *)stream;{
  
    if ([stream.videoTracks count] && stream.videoTracks[0] != nil) {
        RTCVideoTrack * videoTrack = stream.videoTracks[0];
        self.track = videoTrack;
        [self.track addRenderer:self.EAGLVideoView];
    }else{
        NSLog(@"当前流的tracks %@",stream.videoTracks);
    }
 
}



/** Called when a remote peer closes a stream. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection didRemoveStream:(RTCMediaStream *)stream;{
 }

/** Called when negotiation is needed, for example ICE has restarted. */
- (void)peerConnectionShouldNegotiate:(RTCPeerConnection *)peerConnection;{
 }

/** Called any time the IceConnectionState changes. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
    didChangeIceConnectionState:(RTCIceConnectionState)newState;{
    
 }

/** Called any time the IceGatheringState changes. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
    didChangeIceGatheringState:(RTCIceGatheringState)newState;{
    self.iceGatheringState = newState;
}

/** New ice candidate has been found. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
    didGenerateIceCandidate:(RTCIceCandidate *)candidate;{
 
    if (candidate!= nil) {
        NSData *message = nil;
        NSString *messageStr = @"";
        NSDictionary * dict = @{
            @"cmd":@"candidate",
            @"data":@{
                @"id":candidate.sdpMid,
                @"label":[NSString stringWithFormat:@"%d",candidate.sdpMLineIndex],
                @"candidate":candidate.sdp ,
                @"type":@"candidate",
            }
        };
        
        message = [NSJSONSerialization dataWithJSONObject:dict  options:NSJSONWritingPrettyPrinted error:nil];
        messageStr  = [[NSString alloc] initWithData:message  encoding:NSUTF8StringEncoding];
        NSLog(@"candidateStrig = %@",messageStr);
        if (messageStr.length > 0) {
            [self.IOClient emit:rtc_msg with:@[messageStr]];

        }else{
            [WSProgressHUD showErrorWithStatus:@"数据转换失败"];
        }
        
    }
}
 
/** Called when a group of local Ice candidates have been removed. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
    didRemoveIceCandidates:(NSArray<RTCIceCandidate *> *)candidates;{
 
}

/** New data channel has been opened. */
- (void)peerConnection:(RTCPeerConnection *)peerConnection
    didOpenDataChannel:(RTCDataChannel *)dataChannel;{
}
 
 
// 视频流尺寸改变
- (void)videoView:(RTCEAGLVideoView*)videoView didChangeVideoSize:(CGSize)size
{
    self.remoteVideoStreamSize = size;
    CGFloat H = (size.height /size.width) * KYScreenWidth;
    if (H > KYScreenHeight) {
        CGFloat W = (size.width /size.height) * KYScreenHeight;
        self.EAGLVideoView.frame = CGRectMake(0, 0, W, KYScreenHeight);

    }else{
        self.EAGLVideoView.frame = CGRectMake(0, 0, KYScreenWidth, H);

    }
    self.EAGLVideoView.center = self.view.center;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [WSProgressHUD dismiss];
 
    });
}
 
- (BOOL)prefersStatusBarHidden {
    return YES;
}
 
-(void)initUI{
 
   
    
    self.view.backgroundColor = UIColor.blackColor;
    AppDelegate * delegate = ( AppDelegate *)UIApplication.sharedApplication.delegate;
    
    RTCEAGLVideoView *videoView = [[RTCEAGLVideoView alloc] initWithFrame:CGRectMake(0, [XTCommon getSafePaddingTop], KYScreenWidth, KYScreenHeight - [XTCommon getSafePaddingTop] - [XTCommon getSafePaddingBottom] )];
    
    videoView.transform = CGAffineTransformMakeScale(1, 1);
    videoView.delegate = self;
    [self.view addSubview:videoView];
    self.EAGLVideoView = videoView;
    
//    self.operationView = [XTOperationView operationView];
//    [self.view addSubview:self.operationView];
//    self.operationView.hidden = YES;
 
    
    self.dragMoveView = [[XTDragMoveView alloc] initWithFrame:CGRectMake(0, 0, 0, 0)];
    [self.view addSubview:self.dragMoveView];
    self.dragMoveView.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6];
    self.dragMoveView.layer.cornerRadius = 30;
    self.dragMoveView.layer.masksToBounds = YES;
    self.dragMoveView.isKeepBounds = YES;
    self.dragMoveView.imageView.image = [UIImage imageNamed:@"operation_set"];
    self.dragMoveView.imageView.contentMode = UIViewContentModeCenter;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        self.dragMoveView.frame = CGRectMake(KYScreenWidth - 60, KYScreenHeight - 80, 60, 60);
    });
//    MJWeakSelf
      __weak typeof(self) weakSelf = self;

    self.dragMoveView.clickDragViewBlock = ^(XTDragMoveView *dragView) {
      
//        weakSelf.operationView.hidden = !weakSelf.operationView.hidden;
    };
    
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleEnterForeGround) name:UIApplicationDidBecomeActiveNotification object:nil];
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(handleEnterBackGround) name:UIApplicationDidEnterBackgroundNotification object:nil];

    
    
    [self createOperation];
    
}
// 进入后台
- (void)handleEnterBackGround{
 
    NSDictionary * dic = @{@"type":@(Inactive)};
    [self emitChannelWithDict:dic];
}
// 回到前台
- (void)handleEnterForeGround{
    NSDictionary * dic = @{@"type":@(Resumed)};
    
    [self emitChannelWithDict:dic];
}

-(void)tapGes:(UITapGestureRecognizer *)tap{
    CGPoint p =  [tap locationInView:self.view];
  
    [self sendGesMessage:p type:DragStart];
    
}
// channel 通信
-(BOOL)emitChannelWithDict:(NSDictionary *)dict{
    if (self.dataChannel.readyState == RTCDataChannelStateOpen) {
  
        NSData *dataToSend = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
        RTCDataBuffer * buffer = [[RTCDataBuffer alloc]initWithData:dataToSend isBinary:NO];
        if (buffer != nil) {
            BOOL success =  [self.dataChannel sendData:buffer];

            return success;
        }else{
            [WSProgressHUD showErrorWithStatus:@"数据为空"];
            return NO;
        }
    }
    return NO;
}
  

 
-(void)close{
    [self removeTimer];
 
    [self.IOClient disconnect];
    [self.dataChannel close];
    [self.peerConnection close];
  
}
//显示是否隐藏提示框
- (void)showORHideAlertView;{
    NSLog(@"showORHideAlertView====");
}
-(void)goBack{
    [XTOperationViewController captureInView:self.EAGLVideoView andWriteToFile:[NSString stringWithFormat:@"%d",self.vmModel.id]];

    [self removeTimer];
 
    [self close];
    [self dismissViewControllerAnimated:YES completion:nil];
 }
- (void)dealloc
{
    [[NSNotificationCenter defaultCenter]removeObserver:self];

    [self removeTimer];
 
    [self goBack];
 
}

+(void)captureInView:(UIView *)view andWriteToFile:(NSString *)fileName{
    CGSize size = view.bounds.size;
    CGFloat scale = [UIScreen mainScreen].scale;
    CGRect bounds = view.bounds;
    UIGraphicsBeginImageContextWithOptions(size, NO,scale );
    UIGraphicsBeginImageContext(size);
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];
    [view drawViewHierarchyInRect:bounds afterScreenUpdates:YES];
    
    UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
     
     NSString *path = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingFormat:@"/%@.png",fileName];
    NSData * data =  UIImageJPEGRepresentation( image, 1);
    if (data != nil) {
        [data writeToFile:path atomically:YES];

    }else{
        [WSProgressHUD showErrorWithStatus:@"截图失败"];
    }
}
  
+(BOOL)validateIsValidURL:(NSString *)targetString{
    
    NSString *regex = @"\\b((?:https?://|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,4}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>???“”‘’]))";
    return [self regexPatternResultWithRegex:regex TargetString:targetString];
}
+(BOOL)regexPatternResultWithRegex:(NSString *)regex TargetString:(NSString *)targetString{
    
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",regex];
    return [predicate evaluateWithObject:targetString];
}

 
- (void)dragViewBtnAction:(nonnull UIButton *)sender {
    [self resetTimer];
//    if (self.operationView.hidden == YES) {
//        [self.operationView showView];
//        self.actionMenuStatus = YES;
//    }else{
//        [self.operationView hideView];
//        self.actionMenuStatus = NO;
//    }
}

 

 
 
 
@end

 
